//package cn.com.utt.unms.utils;
//
//import java.sql.SQLException;
//import java.sql.Timestamp;
//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//import java.util.concurrent.ArrayBlockingQueue;
//import org.apache.log4j.Logger;
//import org.springframework.beans.factory.annotation.Autowired;
//import cn.com.utt.unms.mapper.WxCodeMapper;
//import cn.com.utt.unms.pojo.WxCode;
//
//public class PasswordFactory {
//	
//	@Autowired
//	private WxCodeMapper wxCodeMapper;
//	
//	private static Logger logger = Logger.getLogger(PasswordFactory.class);
//	private static Map<Long, ArrayBlockingQueue<Short>> codes = null;
//	private static ArrayBlockingQueue<Short> phoneCodes = null;
//	private static ArrayBlockingQueue<Short> uttWxCodes = null;
//	private static Long interval = 100L;
//
//	private PasswordFactory() {
//
//	}
//
//	static {
//		codes = new HashMap<Long, ArrayBlockingQueue<Short>>();
//		phoneCodes = generateQueue();
//		// 创建codes时应当先查询wx_code表中同一店铺下status为0的记录，从新建queue中删除掉
//		uttWxCodes = generateQueue();
//	}
//
//	// 返回空，表示无法取出，提示稍后再试
//	private String getWXPassword() {
//		Short code = uttWxCodes.poll();
//		if (code != null) {
//			return String.format("%04d", code);
//		} else {
//			return null;
//		}
//	}
//
//	public String getPhonePassword() {
//		// 出队
//		Short code = phoneCodes.poll();
//		// 对于手机密码可以重复，如果队列为空了，就重新合建一次队列
//		if (code != null) {
//			return String.format("%04d", code);
//		} else {
//			// 队列已空， 再次填充队列
//			fillQueue(phoneCodes);
//			code = phoneCodes.poll();
//			return String.format("%04d", code);
//		}
//	}
//
//	private static ArrayBlockingQueue<Short> generateQueue() {
//		List<Short> list = new ArrayList<Short>();
//		for (int i = 0; i < 10000; i++) {
//			list.add((short) i);
//		}
//		Collections.shuffle(list);
//		ArrayBlockingQueue<Short> queue = new ArrayBlockingQueue<Short>(10000);
//		queue.addAll(list);
//		return queue;
//	}
//
//	private void fillQueue(ArrayBlockingQueue<Short> queue) {
//		List<Short> list = new ArrayList<Short>();
//		for (int i = 0; i < 10000; i++) {
//			list.add((short) i);
//		}
//		Collections.shuffle(list);
//		queue.addAll(list);
//	}
//
//	public String getWXPassword(Long cfgId) {
//		if (cfgId == 1) {
//			return getWXPassword();
//		} else {
//			Long index = cfgId / interval;
//			ArrayBlockingQueue<Short> queue = codes.get(index);
//			if (queue != null) {
//				logger.info("queue size " + queue.size());
//				Short code = queue.poll();
//				if (code != null) {
//					return String.format("%04d", code);
//				} else {
//					// 尝试回收code
//					recoverWxCode(index);
//					code = queue.poll();
//					if (code != null) {
//						return String.format("%04d", code);
//					} else {
//						// 返回空，表示无法取出，提示稍后再试
//						return null;
//					}
//				}
//			} else {
//				// queue为空需要创建
//				logger.info("queue is null gen first");
//				System.out.println(
//						"queue is null gen first,cfgId:" + cfgId + ",index:" + index + ",interval:" + interval);
//				queue = generateWxQueue(index);
//				codes.put(index, queue);
//				logger.info("queue size is " + queue.size());
//				Short code = queue.poll();
//				if (code != null) {
//					return String.format("%04d", code);
//				} else {
//					// 尝试回收code
//					recoverWxCode(cfgId);
//					code = queue.poll();
//					if (code != null) {
//						return String.format("%04d", code);
//					} else {
//						// 返回空，表示无法取出，提示稍后再试
//						return null;
//					}
//				}
//			}
//		}
//	}
//
//	private ArrayBlockingQueue<Short> generateWxQueue(Long index) {
//		Set<Short> set = new HashSet<Short>();
//		for (int i = 0; i < 10000; i++) {
//			set.add((short) i);
//		}
//		List<WxCode> wxCodes = null;
//		try {
//			Timestamp current = new Timestamp(System.currentTimeMillis());
//			// 将过期的code状态变为已使用。在同一个cfgid区间内只会执行一次，应当将整个区间内的过期code都回收。
//			//WxCodeMapper.updateWxCode(index, index * 100L, current);
//			WxCodeMapper.updateWxCode(1L,"","");
//			// 查询状态为0的code,即没有使用过的
//			wxCodes = WxCodeMapper.queryWxCode(index, index * interval);
//		} catch (SQLException e) {
//			/*
//			 * e.printStackTrace();
//			 */
//			// 记录日志
//			logger.error("gen queue error!", e);
//		}
//		if (wxCodes != null) {
//			// 去掉还没使用过的code
//			logger.info(wxCodes.size() + " code not use");
//			for (WxCode wxCode : wxCodes) {
//				// set.remove(Byte.parseByte(wxCode.getCode()));
//				set.remove(Short.parseShort(wxCode.getCode()));
//			}
//		}
//		List<Short> list = new ArrayList<Short>();
//		list.addAll(set);
//		Collections.shuffle(list);
//		ArrayBlockingQueue<Short> queue = new ArrayBlockingQueue<Short>(10000);
//		queue.addAll(list);
//		return queue;
//	}
//
//	// 用过的密码放回队列
//	public void putWxCode2Queue(Long shopId, String code) {
//		if (shopId == 1) {
//			// utt
//			uttWxCodes.offer(Short.parseShort(code));
//		} else {
//			Long index = shopId / interval;
//			ArrayBlockingQueue<Short> queue = codes.get(index);
//			if (queue != null) {
//				queue.offer(Short.parseShort(code));
//			}
//		}
//	}
//
//	public void recoverWxCode(long index) {
//		WxCodeDao wxCodeDao = new WxCodeDaoImpl();
//		ArrayBlockingQueue<Short> queue = codes.get(index);
//		try {
//			if (queue != null) {
//				Timestamp current = new Timestamp(System.currentTimeMillis());
//				List<WxCode> wxCodes = wxCodeDao.queryExpiredCode(index, index * interval, current);
//				if (wxCodes != null) {
//					logger.info(wxCodes.size() + " code recovered index:" + index);
//					// 更新状态为过期
//					wxCodeDao.updateWxCode(index, index * interval, current);
//					// 放回队列
//					for (WxCode wxCode : wxCodes) {
//						queue.offer(Short.parseShort(wxCode.getCode()));
//					}
//				}
//			}
//		} catch (SQLException e) {
//			logger.error("recover wx code error!", e);
//		}
//	}
//}